package com.cy.pj.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cy.pj.common.annotation.RequiredLog;
import com.cy.pj.common.exception.ServiceException;
import com.cy.pj.common.pojo.JsonResult;
import com.cy.pj.common.pojo.PageObject;
import com.cy.pj.sys.dao.SysGoodsDao;
import com.cy.pj.sys.dao.SysTypeDao;
import com.cy.pj.sys.pojo.SysGoods;
import com.cy.pj.sys.pojo.SysGoodsType;
import com.cy.pj.sys.service.SysGoodsService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.xml.crypto.Data;
import java.util.Date;
import java.util.List;

/**
 * 	在业务层对象的类上添加了@Transactional注解,表示类中所有方法都要进行事务控制:
 * 1)开启事务
 * 2)执行目标方法
 * 3)提交或回滚事务
 * 	FAQ?
 * 1)事务属性timeout的含义是什么?是否允许事务超时,默认不允许(-1),一直等.
 * 2)事务属性rollbackFor表示什么?出现什么异常事务要回滚
 * 3)事务属性readOnly含义是什么?这里的事务是否为只读事务.(只读事务中不允许执行更新操作)
 * 4)事务属性isolation含义是什么?用于设置隔离级别I(多个事务并发执行时可能会出现什么问题?-脏读,不可重复读,幻读)
 * 
 */
@Transactional(timeout =60,rollbackFor =  Throwable.class,readOnly = false
              ,isolation = Isolation.READ_COMMITTED,
               propagation = Propagation.REQUIRED)
@Service
public class SysGoodsServiceImpl implements SysGoodsService {

	//has a
	@Autowired
	private SysGoodsDao sysGoodsDao;

	@Autowired
	private SysTypeDao sysTypeDao;

	
	@Transactional(readOnly = true)
	@RequiredLog(operation = "日志分页查询")
	@Override
	public PageObject<SysGoods> findPageObjects(String goodsname, Integer pageCurrent) {
		System.out.println("SysGoodsServiceImpl.findPageObjects.thread->"+Thread.currentThread().getName());
		//1.参数校验
		if(pageCurrent==null||pageCurrent<1)
			throw new IllegalArgumentException("页码值不正确");
		//2.查询当前页记录
		//使用PageHelper最关键的一个步骤,这里表示启动PageHelper的内置拦截器,拦截查询请求,然后对SQL做处理.
		Page<SysGoods> page=PageHelper.startPage(pageCurrent, 10);//这里的3为pagesize
		List<SysGoods> records=sysGoodsDao.findPageObjects(goodsname);
		//4.封装查询结果并返回
	   return new PageObject<>(page.getTotal(), records, Long.valueOf(page.getPages()), 3, pageCurrent.longValue());
	}

	/**
	 * @RequiresPermissions 注解描述的方法为一个权限控制切入点方法(目标方法),当我们访问此方法时需要授权才能访问?
	 * FAQ:
	 * 1)什么情况下会进行授权?(当用户权限中包含@RequiresPermissions注解内部定义的字符串)
	 * 2)如何获取登录用户的权限标识?(基于登陆用户信息访问用户角色,角色菜单,菜单表中的数据)
	 * 3)由谁授权?(SecurityManager)
	 * 4)在什么样的方法中进行授权?(AOP编程过程中的通知方法中.)
	 * 5)假如用户没有访问此方法的权限怎么办?抛出异常
	 */
//	@RequiresPermissions("sys:goods:update")//"sys:user:update"为一个权限标识
//	@RequiredLog(operation = "禁用启用")
	@Override
	public void validById(Long id, Integer valid) {
		//1.参数校验
		//2.修改状态
		int rows=sysGoodsDao.validById(id, valid);
		//3.验证结果
		if(rows==0)
			throw new ServiceException("记录可能已经不存在");
	}

	@Override
	public JsonResult doFindType() {
		List<SysGoodsType>types=sysTypeDao.doFindType("");
		return new JsonResult(types);
	}

	@Override
	public void saveObject(SysGoods goods) {
		if (StringUtils.isEmpty(goods.getName()))
			throw new RuntimeException("商品名不得为空~~");
		Date date = new Date();
		goods.setCreatedTime(date).setModifiedTime(date);
		sysGoodsDao.saveObject(goods);
		PageObject<SysGoods> objects = findPageObjects("臭袜袜", 1);
		System.out.println(objects);
	}

	@Override
	public JsonResult doFindObjectById(Long id) {
		SysGoods goods = sysGoodsDao.findObjectById(id);
		System.out.println(goods);
		return new JsonResult(goods);
	}

	@Override
	public void updateObject(SysGoods goods) {
		goods.setModifiedTime(new Date());
		sysGoodsDao.updateObject(goods);
	}

	@Override
	public void deleteById(Long id) {
		sysGoodsDao.deleteById(id);
	}


}
